<!DOCTYPE html>
<html lang='en'>

<head>
    <meta charset='UTF-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>Document</title>
    <script src='https://cdn.jsdelivr.net/npm/vue@2.6.14'></script>
</head>

<body>
    <div id='app'>
        <ul>
            <li>姓名: {{student.name}}</li>
            <li>年龄: {{student.age}}</li>
            <li v-if="student.sex">性别: {{student.sex}}</li>
            <li>爱好: 
                <ul>
                    <li v-for="item in student.hobby">{{item}}</li>
                </ul>
            </li>
            <li>朋友: 
                <ul>
                    <li v-for="item in student.friends">姓名: {{item.name}},年龄{{item.age}}</li>
                </ul>
            </li>
        </ul>
        <button @click="changeFirstFriend">把第一个朋友改了</button>
        <button @click="addSex">增加一个性别属性</button>
        <button @click="addFriends">增加一个朋友</button>
        <button @click="change2thFriendsName">把第二个朋友名字改了</button>
        <button @click="removeEat">把吃饭移除</button>
    </div>
    <script>
        /*
            终极无敌版总结:
                1. vue会监视data中所有层次的数据
                2. 如何检测对象中的数据？
                    通过setter实现监视, 且要在new Vue时就传入要监测的数据
                        (1). 对象中后追加的属性,vue默认不做响应式处理
                        (2). 如需给后添加的属性做响应式, 请使用如下API:
                            Vue.set(object/array, propertyName/index,value)
                3. 如何监测数组中的数据?
                    通过包裹数组更新元素的方法实现, 本质就是做了两件事
                        1.调用原生对应的方法对数组进行更新
                        2.重新解析模板, 进而更新页面
                4.在Vue修改数组中的某个元素一定要用如下方法
                    1.使用会改变原数组的js方法，如: push,pop,unshift,shift,splice,sort,reverse
                    2.Vue.set()
                5.注意，不要妄想通过Vue.set()直接给根部的data添加属性
        */
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    student:{
                        name:'mikaisa',
                        age:22,
                        hobby:['吃饭','睡觉','打代码'],
                        friends:[
                            {name:'鹿晗',age:18},
                            {name:'蔡徐坤',age:18}
                        ]
                    }
                }
            },
            methods:{
                addSex(){
                    Vue.set(this.student,'sex','男')
                },
                changeFirstFriend(){
                    Vue.set(this.student.friends,0,{name:'王一博',age:18})
                },
                addFriends(){
                    this.student.friends.push({name:'肖战',age:18})
                },
                change2thFriendsName(){
                    // 也许你会有疑问，你这里不是用了数组的下标吗，这样不是触发不了视图更新的吗？此言差矣，我们之前说的是通过数组的下标直接赋值进行修改，而这里虽然用到了下标，但是我们又往下找了一层，找到了name这个属性，这个时候就不算了，而且name是自带的，不是我们新增的属性，所以可以触发视图更新
                    this.student.friends[1].name = '李汶翰'
                },
                removeEat(){
                    this.student.hobby = this.student.hobby.filter((item)=>{
                        return item!='吃饭'
                    })
                }
            }
        })
    </script>
</body>

</html>